package com.wsg.lightaccounting.DB;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

import com.wsg.lightaccounting.ClassConversion;
import com.wsg.lightaccounting.Model.AA;
import com.wsg.lightaccounting.Model.Account;
import com.wsg.lightaccounting.Model.AccountBooks;
import com.wsg.lightaccounting.Model.AccountManager;
import com.wsg.lightaccounting.Model.CashCard;
import com.wsg.lightaccounting.Model.CreditCard;
import com.wsg.lightaccounting.Model.Customized;
import com.wsg.lightaccounting.Model.Expenditure;
import com.wsg.lightaccounting.Model.Income;
import com.wsg.lightaccounting.Model.IncomeType;
import com.wsg.lightaccounting.Model.Record;
import com.wsg.lightaccounting.Model.RecordManager;
import com.wsg.lightaccounting.Model.ExpenditureType;
import com.wsg.lightaccounting.Model.NetworkPayment;

import java.io.IOException;
import java.text.ParseException;
import java.util.Date;
import java.util.LinkedList;

/**
 * Created by dell-pc on 2016/11/7.
 */

public class DB {
    public static final String DB_NAME_STRING = "LightAccounting_Database.db ";
    public static final String EXPENDITURE_DB_NAME_STRING = "expenditure";
    public static final String INCOME_DB_NAME_STRING = "income";
    public static final String ACCOUNT_DB_NAME_STRING = "account";
    public static final String NETWORK_PAYMENT_DB_NAME_STRING = "network_payment";
    public static final String CASH_CARD_DB_NAME_STRING = "cash_card";
    public static final String CREDIT_CARD_DB_NAME_STRING = "credit_card";
    public static final String CUSTOMIZED_DB_NAME_STRING = "customized";
    public static final String EXPENDITURE_TYPE_DB_NAME_STRING = "expenditure_type";
    public static final String INCOME_TYPE_DB_NAME_STRING = "income_type";
    public static final String ACCOUNT_BOOKS_DB_NAME_STRING = "account_books";
    public static final String AA_DB_NAME_STRING ="aa";

    public static final int VERSION = 1;

    private static DB db = null;
    private SQLiteDatabase sqliteDatabase;
    private DBHelper dbHelper;

    private DB(Context context) throws IOException {
        Log.i("TAG", "run: ");
        dbHelper = new DBHelper(context, DB_NAME_STRING, null, VERSION);
        sqliteDatabase = dbHelper.getWritableDatabase();
    }

    public synchronized static DB getInstance(Context context)
            throws IOException {
        if (db == null) db = new DB(context);
        return db;
    }

    public void getAllAccount(){
        AccountManager.accounts = new LinkedList<Account>();
        AccountManager.cashCards = new LinkedList<CashCard>();
        AccountManager.creditCards = new LinkedList<CreditCard>();
        AccountManager.customizeds = new LinkedList<Customized>();
        AccountManager.networkPayments = new LinkedList<NetworkPayment>();

        Cursor cursor = sqliteDatabase.query(ACCOUNT_DB_NAME_STRING,null,null,null,null,null,null);
        if (cursor.moveToFirst()){
            do {
                Account account = new Account();
                account.setId(cursor.getLong(cursor.getColumnIndex("id")));
                account.setColor(cursor.getInt(cursor.getColumnIndex("color")));
                account.setBalance(cursor.getFloat(cursor.getColumnIndex("balance")));
                account.setType(cursor.getInt(cursor.getColumnIndex("type")));
                AccountManager.accounts.add(account);
            }while (cursor.moveToNext());
            if (cursor != null) cursor.close();
        }

        cursor = sqliteDatabase.query(CASH_CARD_DB_NAME_STRING,null,null,null,null,null,null);
        if (cursor.moveToFirst()){
            do {
                CashCard cashCard = new CashCard();
                cashCard.setId(cursor.getLong(cursor.getColumnIndex("id")));
                cashCard.setCard_id(cursor.getString(cursor.getColumnIndex("card_id")));
                cashCard.setName(cursor.getString(cursor.getColumnIndex("name")));
                cashCard.setBank(cursor.getString(cursor.getColumnIndex("bank")));
                cashCard.setAccount_id(cursor.getLong(cursor.getColumnIndex("account_id")));
                AccountManager.cashCards.add(cashCard);

            }while (cursor.moveToNext());
            if (cursor != null) cursor.close();
        }

        cursor = sqliteDatabase.query(CREDIT_CARD_DB_NAME_STRING,null,null,null,null,null,null);
        if (cursor.moveToFirst()){
            do {
                CreditCard creditCard = new CreditCard();
                creditCard.setId(cursor.getLong(cursor.getColumnIndex("id")));
                creditCard.setCard_id(cursor.getString(cursor.getColumnIndex("card_id")));
                creditCard.setBank(cursor.getString(cursor.getColumnIndex("bank")));
                creditCard.setName(cursor.getString(cursor.getColumnIndex("name")));
                creditCard.setLimit(cursor.getFloat(cursor.getColumnIndex("credit_limit")));
                creditCard.setAccount_id(cursor.getLong(cursor.getColumnIndex("account_id")));
                AccountManager.creditCards.add(creditCard);
            }while (cursor.moveToNext());
            if (cursor != null) cursor.close();
        }
        cursor = sqliteDatabase.query(CUSTOMIZED_DB_NAME_STRING,null,null,null,null,null,null);
        if (cursor.moveToFirst()){
            do {
                Customized customized = new Customized();
                customized.setId(cursor.getLong(cursor.getColumnIndex("id")));
                customized.setName(cursor.getString(cursor.getColumnIndex("name")));
                customized.setAccount_id(cursor.getLong(cursor.getColumnIndex("account_id")));
                AccountManager.customizeds.add(customized);
            }while (cursor.moveToNext());
            if (cursor != null) cursor.close();
        }
        cursor = sqliteDatabase.query(NETWORK_PAYMENT_DB_NAME_STRING,null,null,null,null,null,null);
        if (cursor.moveToFirst()){
            do {
                NetworkPayment networkPayment = new NetworkPayment();
                networkPayment.setId(cursor.getLong(cursor.getColumnIndex("id")));
                networkPayment.setName(cursor.getString(cursor.getColumnIndex("name")));
                networkPayment.setInformation(cursor.getString(cursor.getColumnIndex("information")));
                networkPayment.setAccount_id(cursor.getLong(cursor.getColumnIndex("account_id")));
                AccountManager.networkPayments.add(networkPayment);
            }while (cursor.moveToNext());
            if (cursor != null) cursor.close();
        }
    }

    public void getAllRecord() throws ParseException {
        RecordManager.expenditures = new LinkedList<Expenditure>();
        RecordManager.incomes = new LinkedList<Income>();
        RecordManager.expenditureTypes = new LinkedList<ExpenditureType>();
        RecordManager.incomeTypes = new LinkedList<IncomeType>();
        RecordManager.accountBookses = new LinkedList<AccountBooks>();
        RecordManager.aas = new LinkedList<AA>();
        RecordManager.records =new LinkedList<Record>();


        Cursor cursor = sqliteDatabase.query(EXPENDITURE_DB_NAME_STRING,null,null,null,null,null,null);
        if (cursor.moveToFirst()){
            do {
                Expenditure expenditure = new Expenditure();
                Date date = ClassConversion.longToDate(cursor.getLong(cursor.getColumnIndex("date")), ClassConversion.FORMAT_STRING);
                expenditure.setDate(date);
                expenditure.setMoney(cursor.getFloat(cursor.getColumnIndex("money")));
                expenditure.setConsumptiontype(cursor.getLong(cursor.getColumnIndex("consumption_type")));
                expenditure.setType(cursor.getLong(cursor.getColumnIndex("consumption_type")));
                expenditure.setMoneytype(cursor.getLong(cursor.getColumnIndex("money_type")));
                expenditure.setNotetype(cursor.getLong(cursor.getColumnIndex("note_type")));
                expenditure.setPaytype(cursor.getInt(cursor.getColumnIndex("pay_type")));
                expenditure.setMark(cursor.getString(cursor.getColumnIndex("mark")));
                expenditure.setId(cursor.getLong(cursor.getColumnIndex("id")));
                RecordManager.expenditures.add(expenditure);
                RecordManager.records.add(expenditure);
            }while (cursor.moveToNext());
            if (cursor != null) cursor.close();
        }

        cursor = sqliteDatabase.query(EXPENDITURE_TYPE_DB_NAME_STRING,null,null,null,null,null,null);
        if (cursor.moveToFirst()){
            do {
                ExpenditureType expenditureType = new ExpenditureType();
                expenditureType.setId(cursor.getLong(cursor.getColumnIndex("id")));
                expenditureType.setIcon(cursor.getInt(cursor.getColumnIndex("icon")));
                expenditureType.setIs_show(cursor.getInt(cursor.getColumnIndex("is_show")) == 0 ? false:true);
                expenditureType.setName(cursor.getString(cursor.getColumnIndex("name")));
                RecordManager.expenditureTypes.add(expenditureType);
            }while (cursor.moveToNext());
            if (cursor != null) cursor.close();
        }

        cursor = sqliteDatabase.query(INCOME_DB_NAME_STRING,null,null,null,null,null,null);
        if (cursor.moveToFirst()){
            do {
                Income income = new Income();
                income.setId(cursor.getLong(cursor.getColumnIndex("id")));
                income.setMoney(cursor.getFloat(cursor.getColumnIndex("money")));
                income.setMoneytype(cursor.getLong(cursor.getColumnIndex("money_type")));
                Date date = ClassConversion.longToDate(cursor.getLong(cursor.getColumnIndex("date")), ClassConversion.FORMAT_STRING);
                income.setDate(date);
                income.setIncometype(cursor.getLong(cursor.getColumnIndex("income_type")));
                income.setType(cursor.getLong(cursor.getColumnIndex("income_type")));
                income.setNotetype(cursor.getLong(cursor.getColumnIndex("note_type")));
                income.setMark(cursor.getString(cursor.getColumnIndex("mark")));
                RecordManager.incomes.add(income);
                RecordManager.records.add(income);
            }while (cursor.moveToNext());
            if (cursor != null) cursor.close();
        }

        cursor = sqliteDatabase.query(INCOME_TYPE_DB_NAME_STRING,null,null,null,null,null,null);
        if (cursor.moveToFirst()){
            do {
                IncomeType incomeType = new IncomeType();
                incomeType.setId(cursor.getLong(cursor.getColumnIndex("id")));
                incomeType.setIcon(cursor.getInt(cursor.getColumnIndex("icon")));
                incomeType.setIs_show(cursor.getInt(cursor.getColumnIndex("is_show")) == 0 ? false:true);
                incomeType.setName(cursor.getString(cursor.getColumnIndex("name")));
                RecordManager.incomeTypes.add(incomeType);
            }while (cursor.moveToNext());
            if (cursor != null) cursor.close();
        }

        cursor = sqliteDatabase.query(AA_DB_NAME_STRING,null,null,null,null,null,null);
        if (cursor.moveToFirst()){
            do {
                AA aa = new AA();
                aa.setId(cursor.getLong(cursor.getColumnIndex("id")));
                aa.setName(cursor.getString(cursor.getColumnIndex("name")));
                aa.setMoney(cursor.getFloat(cursor.getColumnIndex("money")));
                aa.setIs_finished(cursor.getInt(cursor.getColumnIndex("is_finished")) == 0 ? false:true);
                aa.setExpenditure_id(cursor.getLong(cursor.getColumnIndex("expenditure_id")));
                RecordManager.aas.add(aa);
            }while (cursor.moveToNext());
            if (cursor != null) cursor.close();
        }

        cursor = sqliteDatabase.query(ACCOUNT_BOOKS_DB_NAME_STRING,null,null,null,null,null,null);
        if (cursor.moveToFirst()){
            do {
                AccountBooks accountBooks = new AccountBooks();
                accountBooks.setId(cursor.getLong(cursor.getColumnIndex("id")));
                accountBooks.setName(cursor.getString(cursor.getColumnIndex("name")));
                RecordManager.accountBookses.add(accountBooks);
            }while (cursor.moveToNext());
            if (cursor != null) cursor.close();
        }
        RecordManager.dataSort();
    }

    //insert
    public long insertAccount(Account account) {
        ContentValues values = new ContentValues();
        putAccount(values,account);
        long insert_id = sqliteDatabase.insert(ACCOUNT_DB_NAME_STRING,null,values);
        account.setId(insert_id);
        return insert_id;

    }
    private void putAccount(ContentValues values,Account account){
        values.put("type",account.getType());
        values.put("balance",account.getBalance());
        values.put("color",account.getColor());
    }
    public long insertAA(AA aa){
        ContentValues values = new ContentValues();
        putAA(values,aa);
        long insert_id = sqliteDatabase.insert(AA_DB_NAME_STRING,null,values);
        aa.setId(insert_id);
        return insert_id;

    }
    private void putAA(ContentValues values,AA aa){
        values.put("name",aa.getName());
        values.put("money",aa.getMoney());
        values.put("is_finished",aa.is_finished());
        values.put("expenditure_id",aa.getExpenditure_id());
    }

    public long insertAccountBooks(AccountBooks accountBooks){
        ContentValues values = new ContentValues();
        putAccountBooks(values,accountBooks);
        long insert_id = sqliteDatabase.insert(ACCOUNT_BOOKS_DB_NAME_STRING,null,values);
        accountBooks.setId(insert_id);
        return insert_id;
    }
    private void putAccountBooks(ContentValues values,AccountBooks accountBooks){
        values.put("name",accountBooks.getName());
    }
    public long insertCashCard(CashCard cashCard){
        ContentValues values = new ContentValues();
        putCashCard(values,cashCard);
        long insert_id = sqliteDatabase.insert(CASH_CARD_DB_NAME_STRING,null,values);
        cashCard.setId(insert_id);
        return insert_id;
    }
    private void putCashCard(ContentValues values,CashCard cashCard){
        values.put("account_id",cashCard.getAccount_id());
        values.put("card_id",cashCard.getCard_id());
        values.put("name",cashCard.getName());
        values.put("bank",cashCard.getBank());
    }
    public long insertCreditCard(CreditCard creditCard){
        ContentValues values = new ContentValues();
        putCreditCard(values,creditCard);
        long insert_id = sqliteDatabase.insert(CREDIT_CARD_DB_NAME_STRING,null,values);
        creditCard.setId(insert_id);
        return insert_id;
    }
    private void putCreditCard(ContentValues values,CreditCard creditCard){
        values.put("card_id",creditCard.getCard_id());
        values.put("bank",creditCard.getBank());
        values.put("name",creditCard.getName());
        values.put("credit_limit",creditCard.getLimit());
        values.put("account_id",creditCard.getAccount_id());
    }
    public long insertCustomized(Customized customized){
        ContentValues values = new ContentValues();
        putCustomized(values,customized);
        long insert_id = sqliteDatabase.insert(CUSTOMIZED_DB_NAME_STRING,null,values);
        customized.setId(insert_id);
        return insert_id;
    }
    private void putCustomized(ContentValues values,Customized customized){
        values.put("name",customized.getName());
        values.put("account_id",customized.getAccount_id());
    }
    public long insertExpenditure( Expenditure expenditure){
        ContentValues values = new ContentValues();
        putExpenditure(values,expenditure);
        long insert_id = sqliteDatabase.insert(EXPENDITURE_DB_NAME_STRING,null,values);
        expenditure.setId(insert_id);
        return insert_id;
    }
    private void putExpenditure(ContentValues values,Expenditure expenditure){
        values.put("money",expenditure.getMoney());
        values.put("consumption_type",expenditure.getConsumptiontype());
        values.put("pay_type",expenditure.getPaytype());
        values.put("money_type",expenditure.getMoneytype());
        values.put("note_type",expenditure.getNotetype());
        values.put("mark",expenditure.getMark());
        long date = ClassConversion.dateToLong(expenditure.getDate());
        values.put("date",date);
    }
    public long insertExpenditureType(ExpenditureType expenditureType){
        ContentValues values = new ContentValues();
        putExpenditureType(values,expenditureType);
        long insert_id = sqliteDatabase.insert(EXPENDITURE_TYPE_DB_NAME_STRING,null,values);
        expenditureType.setId(insert_id);
        return insert_id;
    }
    private void putExpenditureType(ContentValues values,ExpenditureType expenditureType){
        values.put("name",expenditureType.getName());
        values.put("icon",expenditureType.getIcon());
        values.put("is_show",expenditureType.is_show());
    }
    public long insertIncome(Income income){
        ContentValues values = new ContentValues();
        putIncome(values,income);
        long insert_id = sqliteDatabase.insert(INCOME_DB_NAME_STRING,null,values);
        income.setId(insert_id);
        return insert_id;
    }
    private void putIncome(ContentValues values,Income income){
        values.put("money",income.getMoney());
        values.put("income_type",income.getIncometype());
        values.put("money",income.getMoney());
        values.put("money_type",income.getMoneytype());
        values.put("note_type",income.getNotetype());
        long date = ClassConversion.dateToLong(income.getDate());
        values.put("date",date);
    }
    public long insertIncomeType(IncomeType incomeType){
        ContentValues values = new ContentValues();
        putIncomeType(values,incomeType);
        long insert_id = sqliteDatabase.insert(INCOME_DB_NAME_STRING,null,values);
        incomeType.setId(insert_id);
        return insert_id;
    }
    private void putIncomeType(ContentValues values,IncomeType incomeType){
        values.put("name",incomeType.getName());
        values.put("icon",incomeType.getIcon());
        values.put("is_show",incomeType.is_show());

    }
    public long insertNetworkPayment(NetworkPayment networkPayment){
        ContentValues values = new ContentValues();
        putNetworkPayment(values,networkPayment);
        long insert_id = sqliteDatabase.insert(NETWORK_PAYMENT_DB_NAME_STRING,null,values);
        networkPayment.setId(insert_id);
        return insert_id;
    }
    private void putNetworkPayment(ContentValues values,NetworkPayment networkPayment){
        values.put("account_id",networkPayment.getAccount_id());
        values.put("name",networkPayment.getName());
        values.put("information",networkPayment.getInformation());
    }
    //delete
    public long deleteAA(long id) {
        long deletedNumber = sqliteDatabase.delete(AA_DB_NAME_STRING,
                "id = ?",
                new String[]{id + ""});
        return id;
    }

    public long deleteAccount(long id) {
        long deletedNumber = sqliteDatabase.delete(ACCOUNT_DB_NAME_STRING,
                "id = ?",
                new String[]{id + ""});

        return id;
    }
    public long deleteAccountBooks(long id) {
        long deletedNumber = sqliteDatabase.delete(ACCOUNT_BOOKS_DB_NAME_STRING,
                "id = ?",
                new String[]{id + ""});

        return id;
    }

    public long deleteCashCard(long id) {
        long deletedNumber = sqliteDatabase.delete(CASH_CARD_DB_NAME_STRING,
                "id = ?",
                new String[]{id + ""});

        return id;
    }

    public long deleteCreditCard(long id) {
        long deletedNumber = sqliteDatabase.delete(CREDIT_CARD_DB_NAME_STRING,
                "id = ?",
                new String[]{id + ""});

        return id;
    }

    public long deleteCustomized(long id) {
        long deletedNumber = sqliteDatabase.delete(CUSTOMIZED_DB_NAME_STRING,
                "id = ?",
                new String[]{id + ""});

        return id;
    }

    public long deleteExpenditure(long id) {
        long deletedNumber = sqliteDatabase.delete(EXPENDITURE_DB_NAME_STRING,
                "id = ?",
                new String[]{id + ""});

        return id;
    }

    public long deleteExpenditureType(long id) {
        long deletedNumber = sqliteDatabase.delete(EXPENDITURE_TYPE_DB_NAME_STRING,
                "id = ?",
                new String[]{id + ""});

        return id;
    }

    public long deleteIncome(long id) {
        long deletedNumber = sqliteDatabase.delete(INCOME_DB_NAME_STRING,
                "id = ?",
                new String[]{id + ""});
        return id;
    }

    public long deleteIncomeType(long id) {
        long deletedNumber = sqliteDatabase.delete(INCOME_TYPE_DB_NAME_STRING,
                "id = ?",
                new String[]{id + ""});

        return id;
    }

    public long deleteNetworkPayment(long id) {
        long deletedNumber = sqliteDatabase.delete(NETWORK_PAYMENT_DB_NAME_STRING,
                "id = ?",
                new String[]{id + ""});

        return id;
    }
    //update
    public long updateAA(AA aa) {
        ContentValues values = new ContentValues();
        putAA(values,aa);
        sqliteDatabase.update(AA_DB_NAME_STRING, values,
                "id = ?",
                new String[]{aa.getId() + ""});
        return aa.getId();
    }

    public long updateAccount(Account aa) {
        ContentValues values = new ContentValues();
        putAccount(values,aa);
        sqliteDatabase.update(ACCOUNT_DB_NAME_STRING, values,
                "id = ?",
                new String[]{aa.getId() + ""});
        return aa.getId();
    }

    public long updateAccountBooks(AccountBooks aa) {
        ContentValues values = new ContentValues();
        putAccountBooks(values,aa);
        sqliteDatabase.update(ACCOUNT_BOOKS_DB_NAME_STRING, values,
                "id = ?",
                new String[]{aa.getId() + ""});
        return aa.getId();
    }

    public long updateCashCard(CashCard aa) {
        ContentValues values = new ContentValues();
        putCashCard(values,aa);
        sqliteDatabase.update(CASH_CARD_DB_NAME_STRING, values,
                "id = ?",
                new String[]{aa.getId() + ""});
        return aa.getId();
    }

    public long updateCreditCard(CreditCard aa) {
        ContentValues values = new ContentValues();
        putCreditCard(values,aa);
        sqliteDatabase.update(CREDIT_CARD_DB_NAME_STRING, values,
                "id = ?",
                new String[]{aa.getId() + ""});
        return aa.getId();
    }

    public long updateCustomized(Customized aa) {
        ContentValues values = new ContentValues();
        putCustomized(values,aa);
        sqliteDatabase.update(CUSTOMIZED_DB_NAME_STRING, values,
                "id = ?",
                new String[]{aa.getId() + ""});

        return aa.getId();
    }

    public long updateExpenditure(Expenditure aa) {
        ContentValues values = new ContentValues();
        putExpenditure(values,aa);
        sqliteDatabase.update(EXPENDITURE_DB_NAME_STRING, values,
                "id = ?",
                new String[]{aa.getId() + ""});
        return aa.getId();
    }

    public long updateExpenditureType(ExpenditureType aa) {
        ContentValues values = new ContentValues();
        putExpenditureType(values,aa);
        sqliteDatabase.update(EXPENDITURE_TYPE_DB_NAME_STRING, values,
                "id = ?",
                new String[]{aa.getId() + ""});
        return aa.getId();
    }

    public long updateIncome(Income aa) {
        ContentValues values = new ContentValues();
        putIncome(values,aa);
        sqliteDatabase.update(INCOME_DB_NAME_STRING, values,
                "id = ?",
                new String[]{aa.getId() + ""});
        return aa.getId();
    }

    public long updateIncomeType(IncomeType aa) {
        ContentValues values = new ContentValues();
        putIncomeType(values,aa);
        sqliteDatabase.update(INCOME_TYPE_DB_NAME_STRING, values,
                "id = ?",
                new String[]{aa.getId() + ""});
        return aa.getId();
    }

    public long updateNetworkPayment(NetworkPayment aa) {
        ContentValues values = new ContentValues();
        putNetworkPayment(values,aa);
        sqliteDatabase.update(NETWORK_PAYMENT_DB_NAME_STRING, values,
                "id = ?",
                new String[]{aa.getId() + ""});
        return aa.getId();
    }

}
